package com.zbkj.service.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.common.exception.AppException;
import com.zbkj.common.model.merchant.MerchantCategory;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.merchant.MerchantCategoryBrandRequest;
import com.zbkj.common.request.merchant.MerchantCategoryRequest;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.response.MerchantCategoryListResponse;
import com.zbkj.common.response.MerchantCategoryPageListResponse;
import com.zbkj.common.result.CommonResultCode;
import com.zbkj.common.result.MerchantResultCode;
import com.zbkj.service.dao.MerchantCategoryDao;
import com.zbkj.service.service.MerchantCategoryService;
import com.zbkj.service.service.MerchantService;
import com.zbkj.service.util.BrandUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * StoreCategoryServiceImpl 接口实现
 +----------------------------------------------------------------------
 */
@Service
public class MerchantCategoryServiceImpl extends ServiceImpl<MerchantCategoryDao, MerchantCategory> implements MerchantCategoryService {

    @Resource
    private MerchantCategoryDao dao;

    @Autowired
    private MerchantService merchantService;

    /**
     * 获取商户分类分页列表
     * @param pageParamRequest 分页参数
     * @return PageInfo
     */
    @Override
    public PageInfo<MerchantCategory> getAdminPage(PageParamRequest pageParamRequest) {
        Page<MerchantCategory> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        LambdaQueryWrapper<MerchantCategory> lqw = Wrappers.lambdaQuery();
        lqw.eq(MerchantCategory::getIsDel, false);
        lqw.eq(MerchantCategory::getBrandId, BrandUtil.getBrandIdByUrl());
        lqw.orderByAsc(MerchantCategory::getSort);
        lqw.orderByDesc(MerchantCategory::getId);
        List<MerchantCategory> categoryList = dao.selectList(lqw);
        return CommonPage.copyPageInfo(page, categoryList);
    }

    @Override
    public PageInfo<MerchantCategoryPageListResponse> getAdminPageBrand(PageParamRequest pageParamRequest) {
        Page<MerchantCategory> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        LambdaQueryWrapper<MerchantCategory> lqw = Wrappers.lambdaQuery();
        lqw.eq(MerchantCategory::getIsDel, false);
        lqw.eq(MerchantCategory::getBrandId, BrandUtil.getBrandIdByUrl());
        lqw.orderByAsc(MerchantCategory::getSort);
        lqw.orderByDesc(MerchantCategory::getId);
        List<MerchantCategory> categoryList = dao.selectList(lqw);
        List<MerchantCategoryPageListResponse> shortplayItemsResponses = new ArrayList<>();
        categoryList.stream().forEach(items->{
            MerchantCategoryPageListResponse shortplayItemsResponse = new MerchantCategoryPageListResponse();
            BeanUtils.copyProperties(items, shortplayItemsResponse);
            // 上级分类名称
            if (items.getPid() != null && items.getPid() > 0) {
                MerchantCategory category = this.getNameById(items.getPid());
                shortplayItemsResponse.setParentName(category.getName());
            }
            shortplayItemsResponses.add(shortplayItemsResponse);
        });
        return CommonPage.copyPageInfo(page, shortplayItemsResponses);
    }

    private MerchantCategory getNameById(Integer pid) {
        LambdaQueryWrapper<MerchantCategory> lqw = Wrappers.lambdaQuery();
        lqw.select(MerchantCategory::getName);
        lqw.eq(MerchantCategory::getIsDel, false);
        lqw.eq(MerchantCategory::getId, pid);
        return getOne(lqw);
    }

    /**
     * 添加商户分类
     * @param request 请求参数
     * @return Boolean
     */
    @Override
    public Boolean add(MerchantCategoryRequest request) {
        if (checkName(request.getName())) {
            throw new AppException(CommonResultCode.VALIDATE_FAILED, "分类名称重复");
        }
        MerchantCategory merchantCategory = new MerchantCategory();
        BeanUtils.copyProperties(request, merchantCategory);
        merchantCategory.setId(null);
        merchantCategory.setBrandId(BrandUtil.getBrandIdByUrl());
        if (merchantCategory.getSort() == null) {
            merchantCategory.setSort(0);
        }
        return dao.insert(merchantCategory) > 0;
    }

    @Override
    public Boolean addBrand(MerchantCategoryBrandRequest request) {
        if (checkName(request.getName())) {
            throw new AppException(CommonResultCode.VALIDATE_FAILED, "分类名称重复");
        }
        MerchantCategory merchantCategory = new MerchantCategory();
        BeanUtils.copyProperties(request, merchantCategory);
        merchantCategory.setId(null);
        merchantCategory.setBrandId(BrandUtil.getBrandIdByUrl());
        if (merchantCategory.getSort() == null) {
            merchantCategory.setSort(0);
        }
        return dao.insert(merchantCategory) > 0;
    }

    /**
     * 编辑商户分类
     * @param request 请求参数
     * @return Boolean
     */
    @Override
    public Boolean edit(MerchantCategoryRequest request) {
        if (ObjectUtil.isNull(request.getId())) {
            throw new AppException(CommonResultCode.VALIDATE_FAILED, "分类ID不能为空");
        }
        MerchantCategory category = getByIdException(request.getId());
        if (!category.getName().equals(request.getName())) {
            if (checkName(request.getName())) {
                throw new AppException(CommonResultCode.VALIDATE_FAILED, "分类名称重复");
            }
        }
        if (!BrandUtil.getBrandIdByUrl().equals(0) && !BrandUtil.getBrandIdByUrl().equals(category.getBrandId())) {
            throw new AppException("无权限操作此数据");
        }
        BeanUtils.copyProperties(request, category);
        category.setId(request.getId());
        if (category.getSort() == null) {
            category.setSort(0);
        }
        return dao.updateById(category) > 0;
    }

    /**
     * 删除商户分类
     * @param id 商户分类ID
     * @return Boolean
     */
    @Override
    public Boolean delete(Integer id) {
        MerchantCategory category = getByIdException(id);
        if (merchantService.isExistCategory(category.getId())) {
            throw new AppException(MerchantResultCode.MERCHANT_CATEGORY_USED);
        }
        if (!BrandUtil.getBrandIdByUrl().equals(0) && !BrandUtil.getBrandIdByUrl().equals(category.getBrandId())) {
            throw new AppException("无权限操作此数据");
        }
        category.setIsDel(true);
        return dao.updateById(category) > 0;
    }

    /**
     * 全部商户列表
     * @return List
     */
    @Override
    public List<MerchantCategory> allList() {
        LambdaQueryWrapper<MerchantCategory> lqw = Wrappers.lambdaQuery();
        lqw.select(MerchantCategory::getId, MerchantCategory::getName, MerchantCategory::getHandlingFee);
        lqw.eq(MerchantCategory::getIsDel, false);
        lqw.orderByAsc(MerchantCategory::getSort);
        lqw.orderByDesc(MerchantCategory::getId);
        return dao.selectList(lqw);
    }

    @Override
    public List<MerchantCategory> allListBrand() {
        LambdaQueryWrapper<MerchantCategory> lqw = Wrappers.lambdaQuery();
        lqw.select(MerchantCategory::getId, MerchantCategory::getName, MerchantCategory::getHandlingFee);
        lqw.eq(MerchantCategory::getIsDel, false);
        lqw.eq(MerchantCategory::getBrandId, BrandUtil.getBrandIdByUrl());
        lqw.orderByAsc(MerchantCategory::getSort);
        lqw.orderByDesc(MerchantCategory::getId);
        return dao.selectList(lqw);
    }

    /**
     * 全部商户分类Map
     * @return Map
     */
    @Override
    public Map<Integer, MerchantCategory> allMap() {
        List<MerchantCategory> categoryList = allList();
        Map<Integer, MerchantCategory> map = CollUtil.newHashMap();
        categoryList.forEach(c -> {
            map.put(c.getId(), c);
        });
        return map;
    }

    @Override
    public Map<Integer, MerchantCategory> allMapBrand() {
        List<MerchantCategory> categoryList = allListBrand();
        Map<Integer, MerchantCategory> map = CollUtil.newHashMap();
        categoryList.forEach(c -> {
            map.put(c.getId(), c);
        });
        return map;
    }

    /**
     * 校验名称是否唯一
     * @param name 分类名称
     */
    private Boolean checkName(String name) {
        LambdaQueryWrapper<MerchantCategory> lqw = Wrappers.lambdaQuery();
        lqw.select(MerchantCategory::getId);
        lqw.eq(MerchantCategory::getName, name);
        lqw.eq(MerchantCategory::getIsDel, false);
        lqw.eq(MerchantCategory::getBrandId, BrandUtil.getBrandIdByUrl());
        lqw.last(" limit 1");
        MerchantCategory merchantCategory = dao.selectOne(lqw);
        return ObjectUtil.isNotNull(merchantCategory);
    }

    /**
     * 通过id获取并抛出异常
     * @param id 分类ID
     * @return MerchantCategory
     */
    @Override
    public MerchantCategory getByIdException(Integer id) {
        MerchantCategory category = getById(id);
        if (ObjectUtil.isNull(category) || category.getIsDel()) {
            throw new AppException(MerchantResultCode.MERCHANT_CATEGORY_NOT_EXIST);
        }
        return category;
    }

    /**
     * 检查数据或复制平台数据
     */
    @Override
    public void checkOrCopy() {
        LambdaQueryWrapper<MerchantCategory> lqw = Wrappers.lambdaQuery();
        lqw.eq(MerchantCategory::getIsDel, false);
        lqw.eq(MerchantCategory::getBrandId, BrandUtil.getBrandIdByUrl());
        if (dao.selectCount(lqw) == 0) {
            // 复制平台数据
            List<MerchantCategory> categoryList = this.getPlatformCategoryList();
            List<MerchantCategory> newCategoryList = new ArrayList<>();
            Date date = new Date();
            if (CollUtil.isNotEmpty(categoryList)) {
                categoryList.forEach(category -> {
                    category.setId(null);
                    category.setBrandId(BrandUtil.getBrandIdByUrl());
                    category.setCreateTime(date);
                    category.setUpdateTime(date);
                    newCategoryList.add(category);
                });
                if (CollUtil.isNotEmpty(newCategoryList)) {
                    saveBatch(newCategoryList);
                }
            }
        }

    }

    @Override
    public List<MerchantCategoryListResponse> getPlatformList() {
        LambdaQueryWrapper<MerchantCategory> lqw = Wrappers.lambdaQuery();
        lqw.eq(MerchantCategory::getIsDel, false);
        lqw.eq(MerchantCategory::getBrandId, 0);
        lqw.orderByAsc(MerchantCategory::getSort);
        lqw.orderByDesc(MerchantCategory::getId);
        List<MerchantCategory> merchantCategories = dao.selectList(lqw);
        if (CollUtil.isEmpty(merchantCategories)) {
            return new ArrayList<>();
        }
        List<MerchantCategoryListResponse> communityStatRecordResponses = new ArrayList<>();
        for (MerchantCategory merchantCategory : merchantCategories) {
            MerchantCategoryListResponse communityStatRecordResponse = new MerchantCategoryListResponse();
            BeanUtils.copyProperties(merchantCategory, communityStatRecordResponse);
            communityStatRecordResponses.add(communityStatRecordResponse);
        }
        return communityStatRecordResponses;
    }

    @Override
    public List<MerchantCategory> getListByIds(List<Integer> ids) {
        LambdaQueryWrapper<MerchantCategory> lqw = Wrappers.lambdaQuery();
        lqw.eq(MerchantCategory::getIsDel, false);
        lqw.in(MerchantCategory::getId, ids);
        lqw.orderByAsc(MerchantCategory::getSort);
        lqw.orderByDesc(MerchantCategory::getId);
        return dao.selectList(lqw);
    }

    private List<MerchantCategory> getPlatformCategoryList() {
        LambdaQueryWrapper<MerchantCategory> lqw = Wrappers.lambdaQuery();
        lqw.eq(MerchantCategory::getIsDel, false);
        lqw.eq(MerchantCategory::getBrandId, 0);
        lqw.orderByAsc(MerchantCategory::getSort);
        lqw.orderByDesc(MerchantCategory::getId);
        return dao.selectList(lqw);
    }
}

